# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Block some property modifications:

- gvn:superusers on repository root
  You should set the property before you install this hook:
  svn propset gvn:superusers group:svn-team .
  as once the hook is installed it will prevent non superusers from adding,
  modifying, or removing the property.

- any property with a name not allowed by svn.core.svn_prop_name_is_valid
"""


import svn.fs



def RunHook(hi, logger):
  """Implements gvn.hooks.runner's RunHook interface

  Returns:
    -1: pass and bypass other hooks
    0: pass
    1: fail
    "string": fail and print string to the user
  """

  author = svn.fs.txn_prop(hi.txn, "svn:author", hi.pool)

  for prop in svn.fs.txn_proplist(hi.txn, hi.pool):
    logger.debug("Inspecting syntax of prop %s", prop)
    if not svn.core.svn_prop_name_is_valid(prop):
      if svn.fs.revision_prop(hi.fs, hi.head, prop) is not None:
        logger.debug("Allow modifying bad prop %s since it's existing" % prop)
      else:
        return("Rejecting rev property with forbidden name: '%s' for user %s" %
               (prop, author))


  # first tag on a quick verification of the property name
  for node in hi.paths_changed:
    props = svn.fs.node_proplist(hi.txn_root, node, hi.pool)
    for property in props:
      logger.debug("Found property %s on repository %s" % (property, node))
      # is this a bad property name according to svn?
      if not svn.core.svn_prop_name_is_valid(property):
        # we'll only reject if the property doesn't already exist (we
        # grandfather existing props)
        if not svn.fs.node_prop(hi.head_root, node, property, hi.pool):
          return("Rejecting new property on %s with forbidden name: '%s' for "
                 "user %s" % (node, property, author))

  # We only care about changes to the root of the repository
  if "/" not in hi.paths_changed:
    logger.debug("No changes to /, therefore no node properties to check, pass")
    return 0

  # Get current gvn:superusers value from HEAD.
  old = svn.fs.node_prop(hi.head_root, "", "gvn:superusers", hi.pool)

  # Get new gvn:superusers value from the txn.
  new = svn.fs.node_prop(hi.txn_root, "", "gvn:superusers", hi.pool)

  if old != new:
    return ("user %s cannot modify %s property on repository root"
              % (author, "gvn:superusers"))

  logger.info("all root properties changes accepted, success!")
  return 0
